package com.dc.project.system.service.impl;

import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.dc.common.annotation.DataScope;
import com.dc.common.constant.CustomSqlConstants;
import com.dc.common.exception.ServiceException;
import com.dc.common.utils.PageUtil;
import com.dc.common.utils.StringUtil;
import com.dc.common.vo.ResultVo;
import com.dc.project.system.dao.SysDeptDao;
import com.dc.project.system.dto.SysDeptDto;
import com.dc.project.system.entity.SysDept;
import com.dc.project.system.entity.SysUser;
import com.dc.project.system.service.SysDeptService;
import com.dc.project.system.service.SysRoleDeptService;
import com.dc.project.system.service.SysUserService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.io.Serializable;
import java.util.HashMap;
import java.util.List;

/**
 * 系统组织部门表(SysDept)表服务实现类
 *
 * @author zhuangcy
 * @since 2021-06-01 14:30:42
 */
@Service("sysDeptService")
public class SysDeptServiceImpl extends ServiceImpl<SysDeptDao, SysDept> implements SysDeptService {
    @Autowired
    private SysRoleDeptService sysRoleDeptService;
    @Autowired
    private SysUserService sysUserService;

    /**
     * 通过主键查询单条数据
     *
     * @param id 主键
     * @return
     */
    @Override
    public ResultVo queryById(Serializable id) {
        return ResultVo.success().data(this.getById(id));
    }

    /**
     * 分页查询系统组织部门表
     *
     * @param dto
     * @return
     */
    @DataScope
    @Override
    public ResultVo queryByPage(SysDeptDto dto) {
        QueryWrapper<SysDept> queryWrapper = new QueryWrapper<>();
        IPage<SysDept> page = this.page(PageUtil.convert2PageParam(dto), queryWrapper);
        return ResultVo.success().data(PageUtil.convert2PageResult(page));
    }

    /**
     * 新增系统组织部门表
     *
     * @param sysDept
     * @return
     */
    @Transactional(rollbackFor = Exception.class)
    @Override
    public ResultVo add(SysDept sysDept) {
        LambdaQueryWrapper<SysDept> queryWrapper = new LambdaQueryWrapper<>();
        queryWrapper.eq(SysDept::getDeptCode, sysDept.getDeptCode())
                .last(CustomSqlConstants.LIMIT_1);
        SysDept one = this.getOne(queryWrapper);
        if (null != one) {
            throw new ServiceException(StringUtil.format("{}该编码已存在", sysDept.getDeptCode()));
        }
        changeAncestors(sysDept);
        return ResultVo.verify(this.save(sysDept));
    }

    private void changeAncestors(SysDept sysDept) {
        if (null == sysDept.getParentId()) {
            sysDept.setAncestors("0");
            sysDept.setParentId(0);
        } else {
            SysDept parent = this.getById(sysDept.getParentId());
            if (null == parent) {
                throw new ServiceException("未找到该父类别");
            }
            sysDept.setAncestors(parent.getAncestors() + "," + sysDept.getParentId());
        }
    }

    /**
     * 编辑系统组织部门表
     *
     * @param sysDept
     * @return
     */
    @Transactional(rollbackFor = Exception.class)
    @Override
    public ResultVo edit(SysDept sysDept) {
        LambdaQueryWrapper<SysDept> queryWrapper = new LambdaQueryWrapper<>();
        queryWrapper.eq(SysDept::getDeptCode, sysDept.getDeptCode())
                .last(CustomSqlConstants.LIMIT_1);
        SysDept one = this.getOne(queryWrapper);
        if (null != one && !one.getDeptId().equals(sysDept.getDeptId())) {
            throw new ServiceException(StringUtil.format("{}该编码已存在", sysDept.getDeptCode()));
        }
        changeAncestors(sysDept);
        return ResultVo.verify(this.updateById(sysDept));
    }

    /**
     * 根据主键删除系统组织部门表
     *
     * @param id 主键
     * @return
     */
    @Transactional(rollbackFor = Exception.class)
    @Override
    public ResultVo delete(Serializable id) {
        // 删除时校验部门是否已被使用
        LambdaQueryWrapper<SysUser> queryWrapper = new LambdaQueryWrapper<>();
        queryWrapper.eq(SysUser::getDeptId, id)
                .last(CustomSqlConstants.LIMIT_1);
        SysUser one = sysUserService.getOne(queryWrapper, false);
        if (null != one) {
            return ResultVo.failed().msg("该部门已关联用户，无法删除");
        }
        return ResultVo.verify(this.removeById(id));
    }

    /**
     * 查询系统组织部门表列表
     *
     * @param dto
     * @return
     */
    @DataScope
    @Override
    public ResultVo queryByList(SysDeptDto dto) {
        LambdaQueryWrapper<SysDept> queryWrapper = new LambdaQueryWrapper<>();
        queryWrapper.and(null != dto.getDeptId(),
                lambdaQuery -> lambdaQuery.ne(SysDept::getDeptId, dto.getDeptId())
                        .apply("!find_in_set({0},ancestors)", dto.getDeptId())
                        .isNotNull(SysDept::getAncestors));
        List<SysDept> list = this.list(queryWrapper);
        return ResultVo.success().data(list);
    }

    /**
     * 通过角色id查询部门数据
     *
     * @param roleId
     * @return
     */
    @Override
    public ResultVo getRoleDept(Integer roleId) {
        List<SysDept> list = this.list();
        List<Integer> deptIds = sysRoleDeptService.getDeptIdByRoleId(roleId);
        HashMap<String, Object> result = new HashMap<>(2);
        result.put("depts", list);
        result.put("deptIds", deptIds);
        return ResultVo.success().data(result);
    }
}